﻿using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.IO;
using System.Linq;
using System.Text;
using System.Windows.Forms;
using System.Xml;
using Core;
using GraphControls.Views;

namespace GraphControls
{
    public partial class ProjectsControl : UserControl
    {
        public Project Project { get; private set; }
        private Graph _activeGraph;
        private TreeNode _root;
        [Browsable(false)]
        public bool IsAdded { get; private set; }
        private TabControl _tabControl;
        private List<GraphControl> _graphControls;
        public event EventHandler ProjectOpenEvent;
        public bool IsProjectOpened
        {
            get; private set;
        }
        public ProjectsControl(ref TabControl tabControl)
        {
            _tabControl = tabControl;
            InitializeComponent();
        }

        public void NewProject(string Name)
        {
            Project = new Project();
            Project.Name = Name;
            _tabControl.TabPages.Clear();
            _graphControls.Clear();
            treeView1.Nodes.Clear();
            treeView1.Nodes.Add("Проект: "+Name);
            _root = treeView1.Nodes[0];
            _root.ContextMenuStrip = contextMenuStrip1;
        }

        public void SetMod(List<GraphControl> list)
        {
            _graphControls = list;
        }

        public void PrepToADD()
        {
            IsAdded = false;
        }

        public void AddProc(Graph graph)
        {
            IsAdded = true;
            foreach (Graph schem in Project.Schems)
            {
                schem.MakePassive();
            }
            _root.Nodes.Add(graph.Name);
            graph.MackeItProc();
            Project.AddSchem(graph);
            _activeGraph = graph;
        }

        public void AddChanel(Graph graph)
        {
            IsAdded = true;
            foreach (Graph schem in Project.Schems)
            {
                schem.MakePassive();
            }
            _root.Nodes.Add(graph.Name);
            graph.MakeItChenal();
            Project.AddSchem(graph);
            _activeGraph = graph;
        }

        public Graph GetActive()
        {
            return _activeGraph;
        }

        public bool TryName(string Name)
        {
            var temp = Project.Schems.Where(x => x.Name == Name);
            return temp.Count() <= 0;
        }

        public Project GetProject()
        {
            return Project;
        }

        private void ProjectsControl_Paint(object sender, PaintEventArgs e)
        {
            //if(_project.Schems.Count >0)
            //    DisplaydProject();
        }

        public void OpenXML(XmlDocument xmlDocument)
        {
            var module = xmlDocument.DocumentElement;
            XmlNode assemblys = module.LastChild;
            string s = "";
            Project = new Project();
            NewProject(module.Attributes[0].Value);
            Graph addedGraph;
            foreach (XmlNode assembly in assemblys)
            {
                s = assembly.Name;
                addedGraph = new Graph();
                addedGraph.Name = assembly.Attributes[0].Value;
                switch (s)
                {
                    case "process":
                        {
                            addedGraph.MackeItProc();
                            AddProc(addedGraph);
                            break;
                        }
                    case "channel":
                        {
                            addedGraph.MakeItChenal();
                            AddChanel(addedGraph);
                            break;
                        }
                }
            }

            XmlNodeList moduleItems = module.ChildNodes;
            string[] t = new string[2];
            t[0] = "process";
            t[1] = "channel";
            TypeOfNode typeOfNode;
            foreach (XmlNode xmlNode in moduleItems)
            {
                switch (xmlNode.Name)
                {
                    case "process":
                        {
                            foreach (XmlNode childNode in xmlNode.ChildNodes)
                            {
                                switch (childNode.Name)
                                {
                                    case "port":
                                        {
                                            typeOfNode = childNode.Attributes[3].Value == "cli" ? TypeOfNode.Client : TypeOfNode.Server;
                                            Project.Schems.Where(u => u.Name == xmlNode.Attributes[0].Value).ToArray()[0]
                                                .AddNode(Convert.ToInt32(childNode.Attributes[4].Value),
                                                           Convert.ToInt32(childNode.Attributes[5].Value),
                                                           childNode.Attributes[0].Value, (byte)typeOfNode).SetChanel(childNode.Attributes[1].Value);

                                            break;
                                        }
                                    case "method":
                                        {
                                            Project.Schems.Where(u => u.Name == xmlNode.Attributes[0].Value).ToArray()[0]
                                                .AddNode(Convert.ToInt32(childNode.Attributes[2].Value),
                                                           Convert.ToInt32(childNode.Attributes[3].Value),
                                                           childNode.Attributes[0].Value, (byte)TypeOfNode.Method).SetExit(Convert.ToInt32(childNode.Attributes[1].Value));
                                            break;
                                        }
                                }
                            }
                            break;
                        }
                    case "channel":
                        {
                            foreach (XmlNode childNode in xmlNode.ChildNodes)
                            {
                                typeOfNode = childNode.Attributes[1].Value == "cli" ? TypeOfNode.Client : TypeOfNode.Server;
                                Project.Schems.Where(u => u.Name == xmlNode.Attributes[0].Value).ToArray()[0]
                                                .AddNode(Convert.ToInt32(childNode.Attributes[2].Value),
                                                           Convert.ToInt32(childNode.Attributes[3].Value),
                                                           childNode.Attributes[0].Value, (byte)typeOfNode);
                            }
                            break;
                        }
                    case "include":
                        {
                            Project.Includ.Add(new Includes(Includes.TypeOfInclude.Including) { Value = xmlNode.Attributes[0].Value, Module = xmlNode.Attributes[1].Value });
                            break;
                        }
                    case "param":
                        {
                            Project.Includ.Add(new Includes(Includes.TypeOfInclude.Param) { Id = xmlNode.Attributes[0].Value, Value = xmlNode.Attributes[1].Value });
                            break;
                        }
                }

            }
            foreach (XmlNode proOrchnode in moduleItems)
            {
                if ((proOrchnode.Name == "process") || (proOrchnode.Name == "channel"))
                {
                    Graph temp = Project.Schems.Where(proC => proC.Name == proOrchnode.Attributes[0].Value).ToArray()[0];
                    if (proOrchnode.Attributes[1].Value.Length > 0)
                        temp.Struct.Where(str => str.Id == proOrchnode.Attributes[1].Value).ToArray()[0].MakeStart(temp);
                    foreach (XmlNode childNode in proOrchnode.ChildNodes)
                    {
                        foreach (XmlNode link in childNode.ChildNodes)
                        {
                            if (link.Name != "activate")
                            {
                                Graph graph = Project.Schems.Where(g => g.Name == proOrchnode.Attributes[0].Value).ToArray()[0];
                                Node from = graph.Struct.Where(f => f.Id == childNode.Attributes[0].Value).ToArray()[0];
                                Node to = graph.Struct.Where(tu => tu.Id == link.Attributes[1].Value).ToArray()[0];
                                from.SetLink(to, link.Attributes[0].Value);
                                Link l = from.Linking.Last();
                                l.X = Convert.ToInt32(link.Attributes[2].Value);
                                l.Y = Convert.ToInt32(link.Attributes[3].Value);
                            }
                        }
                    }
                }
            }
            foreach (Graph graph in Project.Schems)
            {
                _tabControl.TabPages.Add(graph.Name);
                GraphControl graphControl = new GraphControl(this);
                _graphControls.Add(graphControl);
                graphControl.Parent = _tabControl.TabPages[_tabControl.TabPages.Count - 1];
                graphControl.Structure = graph;
                graphControl.Dock = DockStyle.Fill;
            }
            foreach (Graph schem in Project.Schems)
            {
                schem.TryNormalize(_tabControl.Width, _tabControl.Height);
            }
            this.Invalidate();
            if (ProjectOpenEvent != null)
            {
                IsProjectOpened = true;
                ProjectOpenEvent(this, null);
            }
        }

        public void OpenXML(string filename)
        {
            XmlDocument doc = new XmlDocument();
            doc.LoadXml(System.IO.File.ReadAllText(filename));
            OpenXML(doc);
        }

        public void ProjectClose()
        {
            IsProjectOpened = false;
        }
        
        public void SaveToXML(string filename)
        {
            string result="<?xml version="+'"'+"1.0"+'"'+" encoding="+'"'+"UTF-8"+'"'+"?>";
            result += "<module id=" + '"' + Project.Name + '"' + " templet=" + '"' + "GPRT" + '"' + " rem=" + '"' + '"' + '>' + "\r\n";
            foreach (Includes includese in Project.Includ)
            {
                result += includese.ToString();
            }
            foreach (Graph graph in Project.Schems)
            {
                result += graph.ToString();
            }
            result +="<assemble id=" + '"' + Project.Name + "Asm" + '"' + " templet=" + '"' + '"' + " rem=" + '"' +
                      '"' + '>' + "\r\n";
            foreach (Graph graph in Project.Schems)
            {
                switch (graph.TypeOf)
                {
                    case Graph.TypeOfGraph.Process:
                        {
                            result += "\t<process id=";
                            break;
                        }
                    case Graph.TypeOfGraph.Chenal:
                        {
                            result += "\t<channel id=";
                            break;
                        } 
                }
                result += '"' + graph.Name + '"' + " module=" + '"' + '"' + "/>" + "\r\n";
            }
            result += "</assemble>"+ "\r\n" + "</module>" + '\n';
            StreamWriter streamWriter = File.CreateText(filename);
            streamWriter.WriteLine(result);
            streamWriter.Flush();
        }

        private void свойстваToolStripMenuItem_Click(object sender, EventArgs e)
        {
            PropertyView propertyView = new PropertyView();
            propertyView.Initialize(Project);
            propertyView.Show(this);
        }

       
        private void contextMenuStrip1_Opening(object sender, CancelEventArgs e)
        {

        }

  

      
            
    }
}
